#ifndef OPENVIEWERXML_VML2SVG
#define OPENVIEWERXML_VML2SVG

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#include <iostream>
#include <map>
#include <utility>
#include <vector>
#include <sstream>
#include <string>

using namespace std;


XERCES_CPP_NAMESPACE_USE

namespace Utility
{

	class FormulaContainer
	{
	public:
		string f_id;
		string f_v;
		string f_p1;
		string f_p2;
		int f_command;

		enum formulaCommand
		{
			val,
			sum,
			product,
			mid,
			abs_,
			min,
			max,
			if_,
			mod,
			atan2_,
			sin_,
			cos_,
			cosatan2,
			sinatan2,
			sqrt_,
			sumangle,
			ellipse,
			tan_
		};

		FormulaContainer();
		FormulaContainer(string id, string v, string p1, string p2, int command);
		FormulaContainer(string id, const char *formula, vector<string> adjlist, DOMNamedNodeMap* styleAttrList);
		string GetResult();
		string ComputeFormula(map<string, FormulaContainer> formulaMap);
		string GetFormulaValue(string value, map<string, FormulaContainer> formulaMap);

	private:
		int FormulaContainer::GetCommand(string eqn);	
		string GetAdjustment(string formulanode, vector<string> adjustment);

	};
	class VML2SVG
	{
	public:
		VML2SVG();
		~VML2SVG();

		void ConvertVML2SVG(xercesc::DOMDocument* doc, map<const XMLCh*, const XMLCh*> *imgmap); 
		map<XMLCh*,XMLCh*> dashStyleList;
		map<string, DOMElement*> shapetypeMap;
		map<const XMLCh*, const XMLCh*> imageMap;


	private:	
		
		DOMElement* SetParentSvgNodeAttr(DOMElement *parent_svg, DOMElement *vml);
		DOMElement* SetParentSvgNodeAttr(DOMElement *parent_svg, DOMElement *shape_node, DOMNamedNodeMap *shapetype_attr_map);

		void ReadFormulaeNode(DOMElement *formulas, map<string,FormulaContainer> *formulaMap, vector<string> adjustList, DOMNamedNodeMap *styleAttrList);
		void ProcessVMLNode(DOMElement *vml, DOMElement *svg);
		void GetSVGRootNode(DOMElement *vml, DOMElement* root);
		const XMLCh* GetAttributeValue(const DOMNamedNodeMap* attr_list, char* id);	
		XMLCh* ReconstructPath(XMLCh* path, vector<string> *adjust, map<string, FormulaContainer> formulae);
		
		DOMElement* HandleImageFill(DOMElement* parent_node, DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		DOMElement* HandleImageData(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeRectNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map );
		void InitializeGroupNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeShapeNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map );
		DOMElement* InitializePathNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeOvalNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeRoundRectNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeTextBoxNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map, DOMNamedNodeMap *parent_attr_map);
		void InitializePolyLineNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		DOMElement* InitializeLineNode(DOMElement* node, DOMElement *svg, DOMNamedNodeMap *vml_attr_map);
		void InitializeShapeTypeNode(DOMElement* node, DOMElement *svg, DOMElement* shape_node, DOMNamedNodeMap *shapetype_attr_map);
		XMLCh* InterpretPath(XMLCh* path, DOMNamedNodeMap *shapetype_attr_map, DOMNamedNodeMap *shape_attr_map,
			map<string, FormulaContainer> formulae);
		void SetTextboxParentNode(DOMElement *svg, DOMElement *parent_svg, DOMElement *text_node, DOMElement *current_parent_node, DOMNamedNodeMap *vml_attr_map);


		string InsertSVGPathVerb(string token, string &prevVerb);
		void PreparePathVerbs(string& token, char key);

		DOMElement* SetNodeAttributes(DOMNamedNodeMap *vml_attr_map, DOMElement* svg_node,DOMElement* vml_node);
		string VML2SVG::GetViewbox(DOMNamedNodeMap *attr_map);
		DOMElement*  HandleStrokeNode(DOMNamedNodeMap *node_attr_map, DOMElement *element, DOMElement *svg);
		void  PopulateDashStyle();
		XMLCh* GetDashStyleValue(const XMLCh* dashstyle);
		XMLCh* GetStrokeDashValue(DOMNamedNodeMap *attr_map, DOMElement* rect_node);
		
	};

	class StyleHelper
	{
	public:
		StyleHelper();	

		void WriteAttribute(DOMElement *node, char* attribute_key, char* attribute_value);
		void WriteAttribute(DOMElement *node, char* attribute_key, XMLCh* attribute_value);	
		//void WriteAttribute(DOMElement *node, char* attribute_key, const XMLCh* attribute_value);
		void ParseStyle(XMLCh* style, map<string,XMLCh*> *styleMap);

		XMLCh* GetWidthfromStyle(map<string,XMLCh*> *styleMap);		
		XMLCh* GetHeightfromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetXcoordinatefromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetYcoordinatefromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetCYfromStyle(map<string,XMLCh*> *styleMap, float ry);
		XMLCh* GetCXfromStyle(map<string,XMLCh*> *styleMap, float rx);	
		XMLCh* GetRXfromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetRYfromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetZAttrfromStyle(DOMNode *wpict);
		XMLCh* GetZAttrfromStyle(map<string,XMLCh*> *styleMap);
		//XMLCh* GetViewBox(styleHandler styleData);
		XMLCh* GetRotateTransformFromStyle(DOMElement *svg_node, float rotate_convert, float coord_x, float coord_y);
		XMLCh* GetRotationAttrFromStyle(map<string,XMLCh*> *styleMap);
		XMLCh* GetFlipAttrFromStyle(map<string,XMLCh*> *styleMap, DOMElement *svg_node);
		XMLCh* GetFlipAttrValueForSVG(string flip_attribute);
		string GetUnits(const XMLCh* attr);
		//string TrimUnits(const XMLCh* attr);

	};

	class ColorHelper{

	public:
		map<XMLCh*,XMLCh*> colorList;
		ColorHelper();
		XMLCh* GetColor(const XMLCh* hexCode);			
		void populateMap();
		XMLCh* ParseFillColor(const XMLCh* fillcolor);
	};
}
#endif